import { BaseEntity } from '../domain/entities/BaseEntity';
import { Player } from '../domain/entities/Player';
import { Skill } from '../domain/entities/Skill';
import { ModernBaseService } from '../service/base/ModernBaseService';
import { SkillUse, ActiveBuff } from "../core/rpg/types";
import { Attribute_base } from "../shared/face/enums";

/**
 * RPG数据访问层
 * 职责：
 * 1. 玩家RPG数据的持久化
 * 2. 技能和属性数据管理
 * 3. 战斗状态数据缓存
 * 4. 角色成长数据存储
 */
export class RPGRepository extends ModernBaseService {
    private playerRpgCache = new Map<string, CachedRpgData>();
    private readonly CACHE_TTL = 300000; // 5分钟缓存

    /**
     * 获取玩家RPG数据
     * @param playerId 玩家ID
     * @returns RPG数据
     */
    async getPlayerRPGData(playerId: string): Promise<PlayerRPGData> {
        return this.cached(`rpg_${playerId}`, async () => {
            this.validateRequiredParams({ playerId }, ['playerId']);

            const player = this.sdk.getPlayerById(playerId);
            if (!player) {
                throw new Error(`Player ${playerId} not found`);
            }

            // 从玩家组件获取RPG数据
            const rpgComponent = player.getComponent('RPG');
            if (!rpgComponent) {
                // 如果没有RPG组件，创建默认数据
                return this.createDefaultRPGData(playerId);
            }

            // 转换为标准格式
            const rpgData: PlayerRPGData = {
                playerId,
                level: rpgComponent.level || 1,
                experience: rpgComponent.exp || 0,
                attributes: this.convertAttributes(rpgComponent),
                skills: this.convertSkillsToEntities(rpgComponent.skills || []),
                buffs: this.convertBuffs(rpgComponent.buffs || []),
                stats: this.calculateStats(rpgComponent),
                lastUpdated: new Date()
            };

            return rpgData;
        }, this.CACHE_TTL);
    }

    /**
     * 保存玩家RPG数据
     * @param playerId 玩家ID
     * @param rpgData RPG数据
     */
    async savePlayerRPGData(playerId: string, rpgData: PlayerRPGData): Promise<void> {
        await this.safeExecute(async () => {
            this.validateRequiredParams({ playerId, rpgData }, ['playerId', 'rpgData']);

            const player = this.sdk.getPlayerById(playerId);
            if (!player) {
                throw new Error(`Player ${playerId} not found`);
            }

            // 获取RPG组件
            let rpgComponent = player.getComponent('RPG');
            if (!rpgComponent) {
                rpgComponent = player.addComponent('RPG');
            }

            // 转换Entity为原始格式并保存
            rpgComponent.level = rpgData.level;
            rpgComponent.exp = rpgData.experience;
            this.applyAttributes(rpgComponent, rpgData.attributes);
            rpgComponent.skills = this.convertEntitiesToSkills(rpgData.skills);
            rpgComponent.buffs = rpgData.buffs;

            // 更新缓存
            this.updateCache(playerId, rpgData);

            this.log(`RPG data saved for player ${playerId}, level: ${rpgData.level}`);
        }, 'savePlayerRPGData');
    }

    /**
     * 获取玩家技能列表
     * @param playerId 玩家ID
     * @returns 技能列表
     */
    async getPlayerSkills(playerId: string): Promise<Skill[]> {
        const rpgData = await this.getPlayerRPGData(playerId);
        return rpgData.skills;
    }

    /**
     * 保存玩家技能
     * @param playerId 玩家ID
     * @param skills 技能列表
     */
    async savePlayerSkills(playerId: string, skills: Skill[]): Promise<void> {
        const rpgData = await this.getPlayerRPGData(playerId);
        rpgData.skills = skills;
        rpgData.lastUpdated = new Date();
        await this.savePlayerRPGData(playerId, rpgData);
    }

    /**
     * 添加技能到玩家
     * @param playerId 玩家ID
     * @param skillData 技能数据
     * @returns 添加结果
     */
    async addSkillToPlayer(playerId: string, skillData: SkillCreateConfig): Promise<SkillOperationResult> {
        return this.withPerformanceMonitoring(async () => {
            const rpgData = await this.getPlayerRPGData(playerId);
            
            // 检查是否已经拥有该技能
            const existingSkill = rpgData.skills.find(skill => skill.id === skillData.id);
            if (existingSkill) {
                return {
                    success: false,
                    message: '已经拥有该技能',
                    skills: rpgData.skills
                };
            }

            // 创建新技能，转换类型以兼容Entity层
            const entitySkillData = {
                ...skillData,
                type: skillData.type as any // 类型转换以兼容Entity层的SkillType枚举
            };
            const newSkill = Skill.create(entitySkillData);
            rpgData.skills.push(newSkill);
            rpgData.lastUpdated = new Date();

            await this.savePlayerRPGData(playerId, rpgData);

            return {
                success: true,
                message: `学会技能: ${newSkill.name}`,
                skills: rpgData.skills
            };
        }, 'addSkillToPlayer');
    }

    /**
     * 升级玩家技能
     * @param playerId 玩家ID
     * @param skillId 技能ID
     * @returns 升级结果
     */
    async upgradePlayerSkill(playerId: string, skillId: string): Promise<SkillUpgradeResult> {
        return this.withPerformanceMonitoring(async () => {
            const rpgData = await this.getPlayerRPGData(playerId);
            
            const skill = rpgData.skills.find(s => s.id === skillId);
            if (!skill) {
                return {
                    success: false,
                    message: '技能不存在',
                    beforeLevel: 0,
                    afterLevel: 0
                };
            }

            const upgradeResult = (skill as any).upgrade();
            if (!upgradeResult.success) {
                return {
                    success: false,
                    message: upgradeResult.message,
                    beforeLevel: upgradeResult.currentLevel,
                    afterLevel: upgradeResult.currentLevel
                };
            }

            rpgData.lastUpdated = new Date();
            await this.savePlayerRPGData(playerId, rpgData);

            return {
                success: true,
                message: `${skill.name} 升级成功！${upgradeResult.currentLevel - 1}级 -> ${upgradeResult.currentLevel}级`,
                beforeLevel: upgradeResult.currentLevel - 1,
                afterLevel: upgradeResult.currentLevel,
                skill
            };
        }, 'upgradePlayerSkill');
    }

    /**
     * 获取玩家属性详情
     * @param playerId 玩家ID
     * @returns 属性详情
     */
    async getPlayerAttributes(playerId: string): Promise<PlayerAttributeDetails> {
        const rpgData = await this.getPlayerRPGData(playerId);
        
        // 计算基础属性、装备属性和总属性
        const baseAttributes = { ...rpgData.attributes };
        const equipAttributes = await this.calculateEquipAttributes(playerId);
        const totalAttributes: Record<string, number> = {};

        // 合并基础属性和装备属性
        for (const attr in baseAttributes) {
            totalAttributes[attr] = baseAttributes[attr] + (equipAttributes[attr] || 0);
        }

        return {
            playerId,
            baseAttributes,
            equipAttributes,
            totalAttributes,
            powerRating: this.calculatePowerRating(totalAttributes)
        };
    }

    /**
     * 更新玩家属性
     * @param playerId 玩家ID
     * @param attributes 属性对象
     */
    async updatePlayerAttributes(playerId: string, attributes: Record<string, number>): Promise<void> {
        const rpgData = await this.getPlayerRPGData(playerId);
        
        // 更新属性
        for (const [attr, value] of Object.entries(attributes)) {
            rpgData.attributes[attr] = value;
        }

        rpgData.lastUpdated = new Date();
        await this.savePlayerRPGData(playerId, rpgData);
    }

    /**
     * 添加经验值
     * @param playerId 玩家ID
     * @param exp 经验值
     * @returns 升级结果
     */
    async addExperience(playerId: string, exp: number): Promise<LevelUpResult> {
        return this.withPerformanceMonitoring(async () => {
            const rpgData = await this.getPlayerRPGData(playerId);
            
            const oldLevel = rpgData.level;
            const oldExp = rpgData.experience;
            
            rpgData.experience += exp;
            
            // 检查是否升级
            const expForNextLevel = this.getExpRequiredForLevel(rpgData.level + 1);
            const leveledUp = rpgData.experience >= expForNextLevel;
            
            if (leveledUp) {
                rpgData.level += 1;
                rpgData.experience -= expForNextLevel;
                
                // 升级时增加属性点
                this.applyLevelUpBonuses(rpgData);
            }

            rpgData.lastUpdated = new Date();
            await this.savePlayerRPGData(playerId, rpgData);

            return {
                success: true,
                leveledUp,
                oldLevel,
                newLevel: rpgData.level,
                expGained: exp,
                currentExp: rpgData.experience,
                expForNextLevel: this.getExpRequiredForLevel(rpgData.level + 1)
            };
        }, 'addExperience');
    }

    /**
     * 获取玩家战斗数据
     * @param playerId 玩家ID
     * @returns 战斗数据
     */
    async getPlayerBattleData(playerId: string): Promise<PlayerBattleData> {
        const rpgData = await this.getPlayerRPGData(playerId);
        const attributes = await this.getPlayerAttributes(playerId);
        
        return {
            playerId,
            level: rpgData.level,
            currentHp: rpgData.stats.currentHp,
            maxHp: attributes.totalAttributes[Attribute_base.最大生命值] || 100,
            currentMp: rpgData.stats.currentMp,
            maxMp: rpgData.stats.maxMp,
            attack: attributes.totalAttributes[Attribute_base.物理攻击] || 10,
            magicAttack: attributes.totalAttributes[Attribute_base.魔法攻击] || 10,
            defense: attributes.totalAttributes[Attribute_base.物理防御] || 5,
            magicDefense: attributes.totalAttributes[Attribute_base.魔法防御] || 5,
            skills: rpgData.skills,
            buffs: rpgData.buffs,
            powerRating: attributes.powerRating
        };
    }

    /**
     * 更新战斗状态
     * @param playerId 玩家ID
     * @param battleData 战斗数据
     */
    async updateBattleState(playerId: string, battleData: Partial<PlayerBattleData>): Promise<void> {
        const rpgData = await this.getPlayerRPGData(playerId);
        
        if (battleData.currentHp !== undefined) {
            rpgData.stats.currentHp = battleData.currentHp;
        }
        if (battleData.currentMp !== undefined) {
            rpgData.stats.currentMp = battleData.currentMp;
        }
        if (battleData.buffs !== undefined) {
            rpgData.buffs = battleData.buffs;
        }

        rpgData.lastUpdated = new Date();
        await this.savePlayerRPGData(playerId, rpgData);
    }

    /**
     * 批量操作技能
     * @param playerId 玩家ID
     * @param operations 操作列表
     * @returns 批量操作结果
     */
    async batchSkillOperations(playerId: string, operations: SkillOperation[]): Promise<BatchSkillResult> {
        return this.batchProcess(operations, async (operation, index) => {
            switch (operation.type) {
                case 'add':
                    return await this.addSkillToPlayer(playerId, operation.skillData!);
                case 'upgrade':
                    return await this.upgradePlayerSkill(playerId, operation.skillId!);
                case 'remove':
                    return await this.removePlayerSkill(playerId, operation.skillId!);
                default:
                    throw new Error(`Unknown operation type: ${operation.type}`);
            }
        }, 'batchSkillOperations');
    }

    /**
     * 移除玩家技能
     * @param playerId 玩家ID
     * @param skillId 技能ID
     * @returns 移除结果
     */
    async removePlayerSkill(playerId: string, skillId: string): Promise<SkillOperationResult> {
        const rpgData = await this.getPlayerRPGData(playerId);
        
        const skillIndex = rpgData.skills.findIndex(skill => skill.id === skillId);
        if (skillIndex === -1) {
            return {
                success: false,
                message: '技能不存在',
                skills: rpgData.skills
            };
        }

        const removedSkill = rpgData.skills.splice(skillIndex, 1)[0];
        rpgData.lastUpdated = new Date();
        
        await this.savePlayerRPGData(playerId, rpgData);

        return {
            success: true,
            message: `移除技能: ${removedSkill.name}`,
            skills: rpgData.skills
        };
    }

    /**
     * 清理过期缓存
     */
    async cleanupCache(): Promise<void> {
        const now = Date.now();
        for (const [playerId, cached] of this.playerRpgCache) {
            if (now - cached.timestamp > this.CACHE_TTL) {
                this.playerRpgCache.delete(playerId);
            }
        }
        this.log(`RPG cache cleanup completed, remaining entries: ${this.playerRpgCache.size}`);
    }

    // ===== 私有辅助方法 =====

    /**
     * 转换属性数据
     */
    private convertAttributes(rpgComponent: any): Record<string, number> {
        const attributes: Record<string, number> = {};
        
        // 基础属性
        Object.values(Attribute_base).forEach(attr => {
            if (typeof attr === 'string') {
                attributes[attr] = rpgComponent.getAttribute ? rpgComponent.getAttribute(attr) : 0;
            }
        });

        return attributes;
    }

    /**
     * 应用属性到组件
     */
    private applyAttributes(rpgComponent: any, attributes: Record<string, number>): void {
        for (const [attr, value] of Object.entries(attributes)) {
            if (rpgComponent.setAttribute) {
                rpgComponent.setAttribute(attr, value);
            } else {
                rpgComponent[attr] = value;
            }
        }
    }

    /**
     * 转换技能为Entity
     */
    private convertSkillsToEntities(skills: SkillUse[]): Skill[] {
        return skills.map(skillData => {
            return Skill.create({
                id: skillData.skillId,
                name: skillData.reName || skillData.skillId,
                description: '',
                level: skillData.level || 1,
                maxLevel: skillData.maxLevel || 10,
                type: (skillData as any).type || 'active',
                data: skillData
            });
        });
    }

    /**
     * 转换Entity为技能数据
     */
    private convertEntitiesToSkills(skills: Skill[]): SkillUse[] {
        return skills.map(skill => ({
            skillId: skill.id,
            reName: skill.name,
            level: skill.level,
            maxLevel: skill.maxLevel,
            permanentBoosts: {},
            useCount: 0,
            type: skill.type as any,
            ...(skill.data || {})
        }));
    }

    /**
     * 转换Buff数据
     */
    private convertBuffs(buffs: any[]): ActiveBuff[] {
        return buffs.map(buff => ({
            ...buff,
            remainingTurns: buff.remainingTurns || 0
        }));
    }

    /**
     * 计算统计数据
     */
    private calculateStats(rpgComponent: any): PlayerStats {
        return {
            currentHp: rpgComponent.currentHp || rpgComponent.getAttribute?.(Attribute_base.最大生命值) || 100,
            maxHp: rpgComponent.getAttribute?.(Attribute_base.最大生命值) || 100,
            currentMp: rpgComponent.currentMp || 50,
            maxMp: rpgComponent.maxMp || 50
        };
    }

    /**
     * 计算装备属性
     */
    private async calculateEquipAttributes(playerId: string): Promise<Record<string, number>> {
        // 这里需要从装备系统获取装备属性加成
        // 暂时返回空对象
        return {};
    }

    /**
     * 计算战力评分
     */
    private calculatePowerRating(attributes: Record<string, number>): number {
        let power = 0;
        
        // 基础属性权重
        const weights = {
            [Attribute_base.物理攻击]: 2.0,
            [Attribute_base.魔法攻击]: 2.0,
            [Attribute_base.物理防御]: 1.5,
            [Attribute_base.魔法防御]: 1.5,
            [Attribute_base.最大生命值]: 0.1
        };

        for (const [attr, value] of Object.entries(attributes)) {
            const weight = (weights as any)[attr] || 1.0;
            power += value * weight;
        }

        return Math.floor(power);
    }

    /**
     * 获取升级所需经验
     */
    private getExpRequiredForLevel(level: number): number {
        return level * 100; // 简单的经验公式
    }

    /**
     * 应用升级奖励
     */
    private applyLevelUpBonuses(rpgData: PlayerRPGData): void {
        // 每级增加属性点
        rpgData.attributes[Attribute_base.最大生命值] += 10;
        rpgData.attributes[Attribute_base.物理攻击] += 2;
        rpgData.attributes[Attribute_base.魔法攻击] += 2;
        rpgData.attributes[Attribute_base.物理防御] += 1;
        rpgData.attributes[Attribute_base.魔法防御] += 1;
    }

    /**
     * 创建默认RPG数据
     */
    private createDefaultRPGData(playerId: string): PlayerRPGData {
        return {
            playerId,
            level: 1,
            experience: 0,
            attributes: {
                [Attribute_base.最大生命值]: 100,
                [Attribute_base.物理攻击]: 10,
                [Attribute_base.魔法攻击]: 10,
                [Attribute_base.物理防御]: 5,
                [Attribute_base.魔法防御]: 5
            },
            skills: [],
            buffs: [],
            stats: {
                currentHp: 100,
                maxHp: 100,
                currentMp: 50,
                maxMp: 50
            },
            lastUpdated: new Date()
        };
    }

    /**
     * 更新缓存
     */
    private updateCache(playerId: string, rpgData: PlayerRPGData): void {
        this.playerRpgCache.set(playerId, {
            data: rpgData,
            timestamp: Date.now()
        });
    }
}

// ===== 接口定义 =====

/**
 * 玩家RPG数据接口
 */
export interface PlayerRPGData {
    playerId: string;
    level: number;
    experience: number;
    attributes: Record<string, number>;
    skills: Skill[];
    buffs: ActiveBuff[];
    stats: PlayerStats;
    lastUpdated: Date;
}

/**
 * 缓存数据接口
 */
interface CachedRpgData {
    data: PlayerRPGData;
    timestamp: number;
}

/**
 * 玩家统计数据接口
 */
export interface PlayerStats {
    currentHp: number;
    maxHp: number;
    currentMp: number;
    maxMp: number;
}

/**
 * 技能创建配置接口
 */
export interface SkillCreateConfig {
    id: string;
    name: string;
    description: string;
    type: string;
    level?: number;
    maxLevel?: number;
    data?: any;
}

/**
 * 技能操作结果接口
 */
export interface SkillOperationResult {
    success: boolean;
    message: string;
    skills: Skill[];
}

/**
 * 技能升级结果接口
 */
export interface SkillUpgradeResult {
    success: boolean;
    message: string;
    beforeLevel: number;
    afterLevel: number;
    skill?: Skill;
}

/**
 * 玩家属性详情接口
 */
export interface PlayerAttributeDetails {
    playerId: string;
    baseAttributes: Record<string, number>;
    equipAttributes: Record<string, number>;
    totalAttributes: Record<string, number>;
    powerRating: number;
}

/**
 * 升级结果接口
 */
export interface LevelUpResult {
    success: boolean;
    leveledUp: boolean;
    oldLevel: number;
    newLevel: number;
    expGained: number;
    currentExp: number;
    expForNextLevel: number;
}

/**
 * 玩家战斗数据接口
 */
export interface PlayerBattleData {
    playerId: string;
    level: number;
    currentHp: number;
    maxHp: number;
    currentMp: number;
    maxMp: number;
    attack: number;
    magicAttack: number;
    defense: number;
    magicDefense: number;
    skills: Skill[];
    buffs: ActiveBuff[];
    powerRating: number;
}

/**
 * 技能操作接口
 */
export interface SkillOperation {
    type: 'add' | 'upgrade' | 'remove';
    skillId?: string;
    skillData?: SkillCreateConfig;
}

/**
 * 批量技能结果接口
 */
export interface BatchSkillResult {
    success: boolean;
    results: (SkillOperationResult | SkillUpgradeResult)[];
    errors: { index: number; item: SkillOperation; error: string }[];
}
